package com.wg.core.properties;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;

/**
 * 基础属性类
 *
 * @author 少爷123
 */
public abstract class BaseProperties implements IProperties {
    private static final Log log = LogFactory.get();

    @Override
    public String getStr(String key) {
        return getStr(key, null);
    }

    @Override
    public Integer getInt(String key) {
        return getInt(key, null);
    }

    @Override
    public Long getLong(String key) {
        return getLong(key, null);
    }

    @Override
    public Boolean getBool(String key) {
        return getBool(key, null);
    }

    @Override
    public Float getFloat(String key) {
        return getFloat(key, null);
    }

    @Override
    public Double getDouble(String key) {
        return getDouble(key, null);
    }

    @Override
    public Short getShort(String key) {
        return getShort(key, null);
    }

    @Override
    public Byte getByte(String key) {
        return getByte(key, null);
    }

    @Override
    public Date getDate(String key) {
        return getDate(key, null);
    }

    protected void setFieldValue(Object obj, Field field, String key) {
        Class<?> type = field.getType();
        Object value = null;

        try {
            if (type == String.class) {
                value = getStr(key);
            } else if (type == byte.class || type == Byte.class) {
                value = getByte(key);
            } else if (type == short.class || type == Short.class) {
                value = getShort(key);
            } else if (type == long.class || type == Long.class) {
                value = getLong(key);
            } else if (type == int.class || type == Integer.class) {
                value = getInt(key);
            } else if (type == boolean.class || type == Boolean.class) {
                value = getBool(key);
            } else if (type == float.class || type == Float.class) {
                value = getFloat(key);
            } else if (type == Double.class || type == double.class) {
                value = getDouble(key);
            } else if (type == Date.class) {
                value = getDate(key);
            } else if (List.class.isAssignableFrom(type)) {
                Class<?> subClass = (Class<?>) TypeUtil.getTypeArgument(field.getGenericType());
                if (subClass != null) {
                    value = toList(subClass, key);
                } else {
                    log.warn("Unspecified generic type for List field: {}.{}",
                            obj.getClass().getSimpleName(), field.getName());
                }
            } else {
                value = toBean(type, key);
            }

            if (value != null) {
                ReflectUtil.setFieldValue(obj, field, value);
            } else {
                log.debug("No configuration found for key: {}, field: {}", key, field.getName());
            }
        } catch (Exception e) {
            log.error("Error setting field value: {}.{} with key {}",
                    obj.getClass().getName(), field.getName(), key, e);
        }
    }
}
